﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SMA.GENTEv1.Dados;

namespace SMA.GENTEv1
{
    public class TipoProcesso
    {
        #region Variaveis Membro
        private int _idTipoProcesso;
        private string _descricao;
        private TipoRegra _tipoRegra;
        private ProcessoCategoria _processoCategoria;
        private int _idProcessoCategoria;
        private string _preencheProtocolo;
        private string _sigla;
        private List<TipoDocumento> _tipoDocumento;
        private bool _controlaGente;
        private bool _controlaRisco;
        private string _url;
        private Cidade _localidade;
        private GENTEEntities _context;
        #endregion

        #region Propriedades
        public int IdTipoProcesso
        {
            get { return _idTipoProcesso; }
            set { _idTipoProcesso = value; }
        }
        public string Descricao
        {
            get { return _descricao; }
            set { _descricao = value; }
        }
        public TipoRegra TipoRegra
        {
            get { return _tipoRegra; }
            set { _tipoRegra = value; }
        }
        public string Sigla
        {
            get { return _sigla; }
            set { _sigla = value; }
        }
        public ProcessoCategoria ProcessoCategoria
        {
            get { return _processoCategoria; }
            set { _processoCategoria = value; }
        }
        public int IdProcessoCategoria
        {
            get { return _idProcessoCategoria; }
            set { _idProcessoCategoria = value; }
        }
        public string PreencheProtocolo
        {
            get { return _preencheProtocolo; }
            set { _preencheProtocolo = value; }
        }
        public List<TipoDocumento> TipoDocumento
        {
            get { return _tipoDocumento; }
            set { _tipoDocumento = value; }
        }
        public bool ControlaGente
        {
            get { return _controlaGente; }
            set { _controlaGente = value; }
        }
        public bool ControlaRisco
        {
            get { return _controlaRisco; }
            set { _controlaRisco = value; }
        }
        public string Url
        {
            get { return _url; }
            set { _url = value; }
        }
        public Cidade Localidade
        {
            get { return _localidade; }
            set { _localidade = value; }
        }
        #endregion

        #region Construtores
        public TipoProcesso()
        {
            try
            {
                _context = new GENTEEntities();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public TipoProcesso(int idTipoProcesso)
        {
            try
            {
                _context = new GENTEEntities();
                Carregar(idTipoProcesso, false);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public TipoProcesso(int idTipoProcesso, bool controlaGente, bool controlaRisco)
        {
            try
            {
                _context = new GENTEEntities();
                Carregar(idTipoProcesso, false, controlaGente, controlaRisco);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public TipoProcesso(int idTipoProcesso, bool isCarregaTiposDocumentos)
        {
            try
            {
                _context = new GENTEEntities();
                Carregar(idTipoProcesso, isCarregaTiposDocumentos);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public TipoProcesso(int idTipoProcesso, bool controlaGente, bool controlaRisco, int idLocalidade)
        {
            try
            {
                _context = new GENTEEntities();
                Carregar(idTipoProcesso, false, controlaGente, controlaRisco, idLocalidade);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Metodos Privados
        private void Carregar(int idTipoProcesso, bool isCarregaTiposDocumentos)
        {
            try
            {
                var consulta = from tp in _context.tab_tipo_processo
                               where tp.id_tipo_processo == idTipoProcesso
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.descricao,
                                   tp.tab_tipo_regra.id_tipo_regra,
                                   tp.sigla,
                                   tp.tab_processo_categoria.id_processo_categoria,
                                   tp.preenche_protocolo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    this.IdTipoProcesso = list.id_tipo_processo;
                    this.Descricao = list.descricao;
                    this.TipoRegra = new TipoRegra(list.id_tipo_regra);
                    this.ProcessoCategoria = new ProcessoCategoria(list.id_processo_categoria);
                    this.IdProcessoCategoria = list.id_processo_categoria;
                    this.PreencheProtocolo = list.preenche_protocolo;
                    this.Sigla = list.sigla;
                    this.Url = list.url;
                    this.ControlaGente = false;
                    this.ControlaRisco = false;

                    if (isCarregaTiposDocumentos)
                        CarregaTiposDocumentos();
                    
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void Carregar(int idTipoProcesso, bool isCarregaTiposDocumentos, bool controlaGente, bool controlaRisco)
        {
            try
            {
                var consulta = from tp in _context.tab_tipo_processo
                               where tp.id_tipo_processo == idTipoProcesso
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.descricao,
                                   tp.tab_tipo_regra.id_tipo_regra,
                                   tp.sigla,
                                   tp.tab_processo_categoria.id_processo_categoria,
                                   tp.preenche_protocolo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    this.IdTipoProcesso = list.id_tipo_processo;
                    this.Descricao = list.descricao;
                    this.TipoRegra = new TipoRegra(list.id_tipo_regra);
                    this.ProcessoCategoria = new ProcessoCategoria(list.id_processo_categoria);
                    this.IdProcessoCategoria = list.id_processo_categoria;
                    this.PreencheProtocolo = list.preenche_protocolo;
                    this.Sigla = list.sigla;
                    this.Url = list.url;
                    this.ControlaGente = controlaGente;
                    this.ControlaRisco = controlaRisco;

                    if (isCarregaTiposDocumentos)
                        CarregaTiposDocumentos();

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void Carregar(int idTipoProcesso, bool isCarregaTiposDocumentos, bool controlaGente, bool controlaRisco, int idLocalidade)
        {
            try
            {
                var consulta = from tp in _context.tab_tipo_processo
                               where tp.id_tipo_processo == idTipoProcesso
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.descricao,
                                   tp.tab_tipo_regra.id_tipo_regra,
                                   tp.sigla,
                                   tp.tab_processo_categoria.id_processo_categoria,
                                   tp.preenche_protocolo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    this.IdTipoProcesso = list.id_tipo_processo;
                    this.Descricao = list.descricao;
                    this.TipoRegra = new TipoRegra(list.id_tipo_regra);
                    this.ProcessoCategoria = new ProcessoCategoria(list.id_processo_categoria);
                    this.IdProcessoCategoria = list.id_processo_categoria;
                    this.PreencheProtocolo = list.preenche_protocolo;
                    this.Sigla = list.sigla;
                    this.Url = list.url;
                    this.ControlaGente = controlaGente;
                    this.ControlaRisco = controlaRisco;
                    this.Localidade = new Cidade(idLocalidade);

                    if (isCarregaTiposDocumentos)
                        CarregaTiposDocumentos();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        private void CarregaTiposDocumentos()
        {
            try
            {
                TipoDocumento tipoDocumento = new TipoDocumento();
                this.TipoDocumento = tipoDocumento.SelectPorProcesso(this.IdTipoProcesso);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Metodos Publicos

        #region Metodos Publicos - Pesquisa
        public List<TipoProcesso> SelectAll()
        {
            try
            {
                List<TipoProcesso> listTipoProcesso = new List<TipoProcesso>();

                var consulta = from tp in _context.tab_tipo_processo
                               orderby tp.descricao
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.descricao,
                                   tp.tab_tipo_regra.id_tipo_regra,
                                   tp.sigla,
                                   tp.tab_processo_categoria.id_processo_categoria,
                                   tp.preenche_protocolo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    TipoProcesso tipoProcesso = new TipoProcesso();
                    tipoProcesso.IdTipoProcesso = list.id_tipo_processo;
                    tipoProcesso.Descricao = list.descricao;
                    tipoProcesso.TipoRegra = new TipoRegra(list.id_tipo_regra);
                    tipoProcesso.ProcessoCategoria = new ProcessoCategoria(list.id_processo_categoria);
                    tipoProcesso.IdProcessoCategoria = list.id_processo_categoria;
                    tipoProcesso.PreencheProtocolo = list.preenche_protocolo;
                    tipoProcesso.Sigla = list.sigla;
                    tipoProcesso.Url = list.url;
                    tipoProcesso.ControlaGente = false;
                    tipoProcesso.ControlaRisco = false;

                    listTipoProcesso.Add(tipoProcesso);
                }

                return listTipoProcesso;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public List<TipoProcesso> SelectPor(int idProcessoAba)
        {
            try
            {
                List<TipoProcesso> listTipoProcesso = new List<TipoProcesso>();

                var consulta = from tp in _context.tab_tipo_processo
                               where tp.tab_processo_categoria.tab_processo_aba.id_processo_aba == idProcessoAba
                               orderby tp.tab_processo_categoria.descricao, tp.descricao
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.descricao,
                                   tp.tab_tipo_regra.id_tipo_regra,
                                   tp.sigla,
                                   tp.tab_processo_categoria.id_processo_categoria,
                                   tp.preenche_protocolo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    TipoProcesso tipoProcesso = new TipoProcesso();
                    tipoProcesso.IdTipoProcesso = list.id_tipo_processo;
                    tipoProcesso.Descricao = list.descricao;
                    tipoProcesso.TipoRegra = new TipoRegra(list.id_tipo_regra);
                    tipoProcesso.ProcessoCategoria = new ProcessoCategoria(list.id_processo_categoria);
                    tipoProcesso.IdProcessoCategoria = list.id_processo_categoria;
                    tipoProcesso.PreencheProtocolo = list.preenche_protocolo;
                    tipoProcesso.Sigla = list.sigla;
                    tipoProcesso.Url = list.url;
                    tipoProcesso.ControlaGente = false;
                    tipoProcesso.ControlaRisco = false;

                    listTipoProcesso.Add(tipoProcesso);
                }

                return listTipoProcesso;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public List<TipoProcesso> SelectPor(int idProcessoAba, int idContrato)
        {
            try
            {
                List<TipoProcesso> listTipoProcesso = new List<TipoProcesso>();

                var consulta = from tp in _context.tab_tipo_processo
                               where tp.tab_processo_categoria.tab_processo_aba.id_processo_aba == idProcessoAba
                               orderby tp.tab_processo_categoria.descricao, tp.descricao
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.descricao,
                                   tp.tab_tipo_regra.id_tipo_regra,
                                   tp.sigla,
                                   tp.tab_processo_categoria.id_processo_categoria,
                                   tp.preenche_protocolo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    TipoProcesso tipoProcesso = new TipoProcesso();
                    tipoProcesso.IdTipoProcesso = list.id_tipo_processo;
                    tipoProcesso.Descricao = list.descricao;
                    tipoProcesso.TipoRegra = new TipoRegra(list.id_tipo_regra);
                    tipoProcesso.ProcessoCategoria = new ProcessoCategoria(list.id_processo_categoria);
                    tipoProcesso.IdProcessoCategoria = list.id_processo_categoria;
                    tipoProcesso.PreencheProtocolo = list.preenche_protocolo;
                    tipoProcesso.Sigla = list.sigla;
                    tipoProcesso.Url = list.url;

                    ProcessoContrato processoContrato = new ProcessoContrato();

                    tipoProcesso.ControlaGente = processoContrato.RetornaControlaGente(list.id_tipo_processo, idContrato);
                    tipoProcesso.ControlaRisco = processoContrato.RetornaControlaRisco(list.id_tipo_processo, idContrato);

                    listTipoProcesso.Add(tipoProcesso);
                }

                return listTipoProcesso;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public List<TipoProcesso> SelectPorWfConfig(int idWfConfig)
        {
            try
            {
                List<TipoProcesso> listTipoProcesso = new List<TipoProcesso>();

                var consulta = from tp in _context.tab_tipo_processo
                               join tpc in _context.tab_processo_contrato on tp.id_tipo_processo equals tpc.tab_tipo_processo.id_tipo_processo
                               join cw in _context.tab_configuracao_workflow on tpc.id_processo_contrato equals cw.tab_processo_contrato.id_processo_contrato
                               where cw.id_configuracao_workflow == idWfConfig
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.descricao,
                                   tp.tab_tipo_regra.id_tipo_regra,
                                   tp.sigla,
                                   tp.tab_processo_categoria.id_processo_categoria,
                                   tp.preenche_protocolo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    TipoProcesso tipoProcesso = new TipoProcesso();
                    tipoProcesso.IdTipoProcesso = list.id_tipo_processo;
                    tipoProcesso.Descricao = list.descricao;
                    tipoProcesso.TipoRegra = new TipoRegra(list.id_tipo_regra);
                    tipoProcesso.ProcessoCategoria = new ProcessoCategoria(list.id_processo_categoria);
                    tipoProcesso.IdProcessoCategoria = list.id_processo_categoria;
                    tipoProcesso.PreencheProtocolo = list.preenche_protocolo;
                    tipoProcesso.Sigla = list.sigla;
                    tipoProcesso.Url = list.url;

                    ProcessoContrato processoContrato = new ProcessoContrato();

                    listTipoProcesso.Add(tipoProcesso);
                }

                return listTipoProcesso;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<TipoProcesso> SelectPorLocalidade(int idContrato, int idTipoProcesso)
        {
            try
            {
                List<TipoProcesso> listTipoProcesso = new List<TipoProcesso>();

                Contrato contrato = new Contrato(idContrato);
                OrganizacaoPatrocinadorPrestador organRel = new OrganizacaoPatrocinadorPrestador(contrato.OrganizacaoRelacao.IdOrganizacaoRelacao);

                FrotaRegraContrato regracontrato = new FrotaRegraContrato();
                List<Cidade> listCidade = new List<Cidade>();
                listCidade = regracontrato.CarregarLocalidadesOrganizacao(organRel.OrganizacaoPrestador.IdOrganizacao);

                foreach (Cidade cidade in listCidade)
                {
                    TipoProcesso tipoProcesso = new TipoProcesso();
                    tipoProcesso.IdTipoProcesso = idTipoProcesso;
                    tipoProcesso.Localidade = cidade;
                    
                    ProcessoContrato processoContrato = new ProcessoContrato();

                    tipoProcesso.ControlaGente = processoContrato.RetornaControlaGente(idTipoProcesso, idContrato, cidade.IdCidade);
                    tipoProcesso.ControlaRisco = processoContrato.RetornaControlaRisco(idTipoProcesso, idContrato, cidade.IdCidade);

                    listTipoProcesso.Add(tipoProcesso);
                }

                return listTipoProcesso;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string RetornaUrl(int idTipoProcesso)
        {
            try
            {
                string url = string.Empty;

                var consulta = from tp in _context.tab_tipo_processo
                               where tp.id_tipo_processo == idTipoProcesso
                               select new
                               {
                                   tp.id_tipo_processo,
                                   tp.url
                               };

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    url = list.url;
                }

                return url;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Metodos Publicos - Persistencia
        #endregion

        #endregion
    }
}
